package org.springblade.oa.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.jackson.JsonUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.oa.entity.*;
import org.springblade.oa.service.*;
import org.springblade.oa.vo.*;
import org.springblade.oa.wrappper.BxWrapper;
import org.springblade.oa.wrappper.BxfymxWrapper;
import org.springblade.oa.wrappper.BxxcmxWrapper;
import org.springblade.oa.wrappper.BxzszpmxWrapper;
import org.springblade.system.feign.IDictClient;
import org.springblade.system.user.entity.User;
import org.springblade.system.user.entity.UserInfo;
import org.springblade.system.user.feign.IUserClient;
import org.springblade.wechat.entity.MyWxMpTemplateData;
import org.springblade.wechat.entity.MyWxMpTemplateMessage;
import org.springblade.wechat.feign.IMpClient;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @version 1.0.0
 * @Title: BxController.java
 * @Description:
 */

@RestController
@RequestMapping("bxapi")
@AllArgsConstructor
public class BxController {
	private IBxService bxService;
	private IBxfymxService bxfymxService;
	private IBxxcmxService bxxcmxService;
	private IBxzszpmxService bxzszpmxService;
	private IBxshService bxshService;
	private IMessageService messageService;
	private IUserClient userClient;
	private IDictClient dictClient;
	private IMpClient mpClient;
	private IInvoiceImageService iInvoiceImageService;
	/**
	 * 新增或修改
	 */
	@PostMapping("submit")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "新增或修改", notes = "传入报销总表和各类明细表")
	@Transactional(rollbackFor = {Exception.class})
	public R<Map<String, Object>> submit(@RequestBody Map<String, Object> map, HttpServletRequest request, BladeUser user) {
		Map<String, Object> hashMap = new HashMap<>();
		Map<String, String> map1 = (Map) map.get("bx");
		ArrayList bxfymxList = (ArrayList) map.get("bxfymxList");//报销费用明细
		ArrayList xcmxList = (ArrayList) map.get("xcmxList");//行程明细
		ArrayList bxzszpmxList = (ArrayList) map.get("bxzszpmxlist");//报销专票住宿明细
		String resave = map.get("resave").toString();
		Bx bx = JSON.parseObject(JSON.toJSONString(map1), Bx.class);
		bx.setBxrq(new Date());
		//  查询登录人信息
		R<UserInfo> bxuserInfo = userClient.userInfo(user.getUserId().longValue());
		User userInfo= bxuserInfo.getData().getUser();
		//审批部门是否包含自己所属部门
		boolean contain = Func.toStrList(userInfo.getDpprovalDeptId()).contains(userInfo.getDeptId());
		bx.setBmid(Integer.valueOf(bxuserInfo.getData().getUser().getDeptId()));
		//判断提交者角色 部门经理-->待财务审核 会计-->审批通过 出纳-->待财务审核(出纳取消状态）
		try {
			if (bx.getShzt() == 2) {
				//判断为提交还是保存，保存不做处理  提交根据角色给审核状态赋值
				String role = user.getRoleName();
				if (role.indexOf("部门报销审批人") != -1&&contain) {
					bx.setShzt(3);
				} else if (role.indexOf("会计") != -1) {
					bx.setShzt(4);
				}
			}
			//修改报销人为报销人id
			bx.setBxr(user.getUserId());
			SimpleDateFormat df = new SimpleDateFormat("yyyyMM");
			/*if (bx.getBxdw()==1){
				bx.setBxbh( "EF-RB-"+df.format(new Date())+num);
			}else if (bx.getBxdw()==2){
				bx.setBxbh( "OF-RB-"+df.format(new Date())+num);
			}else {
				bx.setBxbh( bx.getBxdw()+"-RB-"+df.format(new Date())+num);
			}*/
			Wrapper<Bx> wrapper = new QueryWrapper<>();
			if (bx.getId() == null) {
				Integer num = bxService.todayCount(0) + 1;
				if (num > 0 && num < 10) {
					bx.setBxbh("RB-" + df.format(new Date()) + "000" + num);
				} else if (num >= 10 && num < 100) {
					bx.setBxbh("RB-" + df.format(new Date()) + "00" + num);
				} else if (num >= 100 && num < 1000) {
					bx.setBxbh("RB-" + df.format(new Date()) + "0" + num);
				}
			}
			switch (bx.getBxlx()) {
				case 1: //差旅
					StringBuilder place = new StringBuilder();
					if (xcmxList != null && xcmxList.size() > 0) {
						for (int i = 0; i < xcmxList.size(); i++) {
							Bxxcmx bxxcmx = JSON.parseObject(JSON.toJSONString(xcmxList.get(i)), Bxxcmx.class);
							if (xcmxList.size() == 1)
								place.append(bxxcmx.getQd() + "-" + bxxcmx.getZd());
							else if (i == 0)
								place.append(bxxcmx.getQd());
							else if (i != xcmxList.size() - 1)
								place.append("-" + bxxcmx.getQd());
							else
								place.append("-" + bxxcmx.getQd() + "-" + bxxcmx.getZd());
						}
						String s = JSON.toJSONString(xcmxList.get(0));
						Bxxcmx first = JSON.parseObject(s, Bxxcmx.class);
						Bxxcmx last = JSON.parseObject(JSON.toJSONString(xcmxList.get(xcmxList.size() - 1)), Bxxcmx.class);
						if(first.getKssj()!=null&&last.getKssj()!=null) {
							String kssj = new SimpleDateFormat("MM/dd").format(first.getKssj());
							String jssj = new SimpleDateFormat("MM/dd").format(last.getJssj());
							String bxabstract = "差旅：" + kssj + "-" + jssj + " " + place.toString();
							bx.setBxabstract(bxabstract);
						}else{
							bx.setBxabstract("差旅：");
						}
					}
					break;
				case 2: //费用
					String fplx = "";
					String bxabstract = "";
					List<String> fylxList = new ArrayList<>();
					if (bxfymxList != null && bxfymxList.size() > 0) {
						for (int i = 0; i < bxfymxList.size(); i++) {
							Bxfymx bxfymx = JSON.parseObject(JSON.toJSONString(bxfymxList.get(i)), Bxfymx.class);
							if (bxfymx.getFplx() == 0) {
								fplx = "无票";
							}
							if (bxfymx.getFylx()!=null&&!"".equals(bxfymx.getFylx())){
								fylxList.add(dictClient.getValue("bx_costtype", Integer.valueOf(bxfymx.getFylx())).getData());
							}
						}
						List newList = fylxList.stream().distinct().collect(Collectors.toList());
						String fylx = String.join(",", newList);
						if (!"".equals(fplx)) {
							bxabstract = "费用：" + fylx + "(" + fplx + ")";
						} else {
							bxabstract = "费用：" + fylx;
						}
						bx.setBxabstract(bxabstract);
					}
					break;
				default: //住宿
					List<String> zsDd = new ArrayList<>();
					if (bxzszpmxList != null && bxzszpmxList.size() > 0) {
						for (int i = 0; i < bxzszpmxList.size(); i++) {
							Bxzszpmx bxzszpmx = JSON.parseObject(JSON.toJSONString(bxzszpmxList.get(i)), Bxzszpmx.class);
							zsDd.add(bxzszpmx.getDd());
							if(i==0&&bxzszpmx.getSfglxc()==1&&bxzszpmx.getBxxcid()!=null){//行程
								Bxxcmx xc = bxxcmxService.getById(bxzszpmx.getBxxcid());
								Bx bxd = bxService.getById(xc.getBxdid());
								bx.setXcmd(bxd.getXcmd());
								bx.setRemarks(bxd.getRemarks());
							}
						}
						List zsList = zsDd.stream().distinct().collect(Collectors.toList());
						String dd = String.join("-", zsList);
						Bxzszpmx first = JSON.parseObject(JSON.toJSONString(bxzszpmxList.get(0)), Bxzszpmx.class);
						Bxzszpmx last = JSON.parseObject(JSON.toJSONString(bxzszpmxList.get(bxzszpmxList.size() - 1)), Bxzszpmx.class);
						if (first.getKssj()!=null&&last.getKssj()!=null) {
							String kssj = new SimpleDateFormat("MM/dd").format(first.getKssj());
							String jssj = new SimpleDateFormat("MM/dd").format(last.getJssj());
							String zsAbstract = "住宿：" + kssj + "-" + jssj + " " + dd;
							bx.setBxabstract(zsAbstract);
						}else{
							bx.setBxabstract( "住宿：");
						}
					}
					break;
			}
			String deptid = userInfo.getDeptId();
			bx.setBmid(Integer.valueOf(deptid));
			bx.setBxrqm(bxuserInfo.getData().getUser().getRealName());
			bxService.submit(bx);
			Integer bxdid = bx.getId();


//			如果是保存  则新增操作信息    消息表新增数据
			if (bx.getShzt() != 1) {
				if (resave.equals("resave")) {
					Bxsh bxsh = new Bxsh();
					bxsh.setBxdid(bxdid);
					bxsh.setShzt(5);//再次提交
					bxshService.save(bxsh);
					//往消息表新增一条待办任务：接收：部门经理/部门审批
					if (user.getRoleName().indexOf("部门报销审批人") != -1&&contain) {
						//修改审批拒绝状态为已修改 新增会计待审批任务
						updateBeforeMesage("1", "2", "1", bx.getId() + "", bx.getBxr() + "", "已修改");
						addMesage("1", "2", "1", bx.getId() + "", "", bxuserInfo.getData().getUser().getRealName() + "提交的报销需要您审批", user.getUserId() + "", "|6#4|", "待审批");
					} else if (user.getRoleName().indexOf("会计") != -1) {
						//修改审批拒绝状态为已修改 新增出纳待审批任务
						updateBeforeMesage("1", "2", "1", bx.getId() + "", bx.getBxr() + "", "已修改");
						addMesage("1", "2", "1", bx.getId() + "", "", bxuserInfo.getData().getUser().getRealName() + "提交的报销需要您终结", user.getUserId() + "", "|6#5|", "待终结");
					} else {
						//修改审批拒绝状态为已修改 新增部门经理待审批任务
						updateBeforeMesage("1", "2", "1", bx.getId() + "", bx.getBxr() + "", "已修改");
						addMesage("1", "2", "1", bx.getId() + "", "", bxuserInfo.getData().getUser().getRealName() + "提交的报销需要您审批", user.getUserId() + "", "|" + deptid + "#" + "11|", "待审批");
					}
				} else if (resave.equals("save")) {
					Bxsh bxsh = new Bxsh();
					bxsh.setBxdid(bxdid);
					bxsh.setShzt(6);//首次提交
					bxshService.save(bxsh);
					if (user.getRoleName().indexOf("部门报销审批人") != -1&&contain) {
						//新增会计待审批任务
						addMesage("1", "2", "1", bx.getId() + "", "", bxuserInfo.getData().getUser().getRealName() + "提交的报销需要您审批", user.getUserId() + "", "|6#4|", "待审批");
					} else if (user.getRoleName().indexOf("会计") != -1) {
						//新增出纳代办任务
						addMesage("1", "2", "1", bx.getId() + "", "", bxuserInfo.getData().getUser().getRealName() + "提交的报销需要您终结", user.getUserId() + "", "|6#5|", "待终结");
					} else {
						//新增部门经理代办任务
						addMesage("1", "2", "1", bx.getId() + "", "", bxuserInfo.getData().getUser().getRealName() + "提交的报销需要您审批", user.getUserId() + "", "|" + deptid + "#" + "11|", "待审批");
					}
				}
			}
			if (bxfymxList != null && bxfymxList.size() > 0) {
				for (int i = 0; i < bxfymxList.size(); i++) {
					Bxfymx bxfymx = JSON.parseObject(JSON.toJSONString(bxfymxList.get(i)), Bxfymx.class);
					bxfymx.setBxdid(bxdid);
					bxfymxService.submit(bxfymx);
				}
			}
			if (xcmxList != null && xcmxList.size() > 0) {
				for (int i = 0; i < xcmxList.size(); i++) {
					Bxxcmx bxxcmx = JSON.parseObject(JSON.toJSONString(xcmxList.get(i)), Bxxcmx.class);
					bxxcmx.setBxdid(bxdid);
					bxxcmxService.submit(bxxcmx);
					//修改关联行程项目Id
					Bxzszpmx bxzszpmx = new Bxzszpmx();
					bxzszpmx.setBxxcid(bxxcmx.getId());
					bxzszpmx.setXmbh(bxxcmx.getXmbh());
					bxzszpmxService.updateXmid(String.valueOf(bxxcmx.getId()), bxxcmx.getXmbh());
				}
			}
			if (bxzszpmxList != null && bxzszpmxList.size() > 0) {
				for (int i = 0; i < bxzszpmxList.size(); i++) {
					Bxzszpmx bxzszpmx = JSON.parseObject(JSON.toJSONString(bxzszpmxList.get(i)), Bxzszpmx.class);
					bxzszpmx.setBxdid(bxdid);
					bxzszpmxService.submit(bxzszpmx);
				}
			}
			hashMap.put("bxId", bx.getId());
			return R.data(hashMap);
		} catch (Exception e) {
			e.printStackTrace();
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();// 事务回滚
			return R.data(hashMap);
		}
	}

	/**
	 * 报销审批
	 */
	@PostMapping("/bxsp")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "报销审批", notes = "传入状态与审批信息")
	@Transactional(rollbackFor = {Exception.class})
	public R update(@RequestBody Map<String, Object> map, BladeUser user) {
		List<Integer> bxids = Func.toIntList(map.get("ids").toString());
		String shResult = map.get("shresult").toString();
		Integer oldshzt = Integer.valueOf(map.get("shzt").toString());
		String bz = map.get("bz").toString();
		try {
			for (int i = 0; i < bxids.size(); i++) {
				Bx bx = bxService.getById(bxids.get(i));
//根据id查询人员的部门id   通过部门id查询部门的部门经理/会计
				Integer bxuserid = bx.getBxr();
				R<UserInfo> bxuserInfo = userClient.userInfo(bxuserid.longValue());
				String deptid = bxuserInfo.getData().getUser().getDeptId();
				R<UserInfo> userInfo = userClient.userInfo(user.getUserId().longValue());
				boolean contain = Func.toStrList(userInfo.getData().getUser().getDpprovalDeptId()).contains(userInfo.getData().getUser().getDeptId());
				//角色
				String role = user.getRoleName();
				Bxsh bxsh = new Bxsh();
				bxsh.setShyj(bz);
				if(shResult.equals("tijiao")){
					if(oldshzt == 1){
						if(user.getRoleId().indexOf("11")>=0&&contain){
							bx.setShzt(3);
						}else{
							bx.setShzt(2);
						}
						bx.setBxrq(new Date());
						bxsh.setShzt(6);
						bxsh.setBxdid(bxids.get(i));
						bxshService.save(bxsh);
						bxService.updateById(bx);
						//审批部门是否包含自己所属部门
						if (user.getRoleName().indexOf("部门报销审批人") != -1) {
							//新增会计待审批任务
							addMesage("1", "2", "1", bx.getId() + "", "", bxuserInfo.getData().getUser().getRealName() + "提交的报销需要您审批", user.getUserId() + "", "|6#4|", "待审批");
						} else if (user.getRoleName().indexOf("会计") != -1) {
							//新增出纳代办任务
							addMesage("1", "2", "1", bx.getId() + "", "", bxuserInfo.getData().getUser().getRealName() + "提交的报销需要您终结", user.getUserId() + "", "|6#5|", "待终结");
						} else {
							//新增部门经理代办任务
							addMesage("1", "2", "1", bx.getId() + "", "", bxuserInfo.getData().getUser().getRealName() + "提交的报销需要您审批", user.getUserId() + "", "|" + deptid + "#" + "11|", "待审批");
						}
						return R.status(true);
					}
				}
				if (shResult.equals("yes")) {

// 如果初始值为审批拒绝，则审批后为部门审批中
					if (oldshzt == 5) {   //重新提交
						bx.setShzt(2);
						bxsh.setShzt(1);
					}
					if (oldshzt == 2 && role.indexOf("部门报销审批人") != -1) {   //部门审批通过
						bx.setShzt(3);
						bxsh.setShzt(1);
						bx.setShrqm(userInfo.getData().getUser().getRealName());
//（新增一条会计的任务-待审批 （2）新增一条人员的审批通过消息 （3）修改部门审批人待办任务状态-已审批
						addMesage("1", "2", "1", bx.getId() + "", "", bxuserInfo.getData().getUser().getRealName() + "提交的报销需要您审批", user.getUserId() + "", "|6" + "#" + "4|", "待审批");
						addMesage("1", "2", "2", bx.getId() + "", "", "您的报销" + userInfo.getData().getUser().getRealName() + "已同意,请知晓", user.getUserId() + "", bx.getBxr() + "", "审批通过");
						updateBeforeMesage("1", "2", "1", bx.getId() + "", "|" + deptid + "#" + "11|", "已审批");
					} else if (oldshzt == 3 && role.indexOf("会计") != -1) {   //会计审批通过
						Integer bxdw = Integer.valueOf(map.get("bxdw").toString());
						bx.setBxdw(bxdw);
						bx.setShzt(4);
						bxsh.setShzt(1);
//（1）新增一条人员的消息-审批通过（2）修改会计待办任务状态（3）新增出纳的代办任务-待审批
						addMesage("1", "2", "2", bx.getId() + "", "", "您的报销" + userInfo.getData().getUser().getRealName() + "已同意,请知晓", user.getUserId() + "", bx.getBxr() + "", "审批通过");
						addMesage("1", "2", "1", bx.getId() + "", "", bxuserInfo.getData().getUser().getRealName() + "提交的报销需要您终结", user.getUserId() + "", "|6#5|", "待终结");
						updateBeforeMesage("1", "2", "1", bx.getId() + "", "|6#4|", "已审批");
					} else if (oldshzt == 4 && role.indexOf("出纳") != -1) {   //审批终结
						bx.setShzt(6);
						bxsh.setShzt(4);
//（1）新增一条人员的消息-审批终结  （2）修改出纳待办任务状态-已审批
						addMesage("1", "2", "2", bx.getId() + "", "", "您的报销" + userInfo.getData().getUser().getRealName() + "已终结，请知晓", user.getUserId() + "", bx.getBxr() + "", "审批终结");
						updateBeforeMesage("1", "2", "1", bx.getId() + "", "|6#5|", "已终结");
					} else {
						R r = new R();
						r.setMsg("当前角色 " + role + " 不能进行" + "审批操作,请确认状态");
						r.setSuccess(false);
						return r;
					}
				} else if (shResult.equals("no")) {//所有状态审批拒绝皆改状态为审批拒绝
					bx.setShzt(5);
					bxsh.setShzt(2);
					if (role.indexOf("部门报销审批人") != -1) {
//部门审批拒绝：（1）新增一条人员的待办任务（2）修改部门审批人待办任务状态
						addMesage("1", "2", "1", bx.getId() + "", bx.getBxlx() + "", "您的报销" + userInfo.getData().getUser().getRealName() + "已拒绝,请修改", user.getUserId() + "", bx.getBxr() + "", "审批拒绝");
						updateBeforeMesage("1", "2", "1", bx.getId() + "", "|" + deptid + "#" + "11|", "已审批");
					} else if (role.indexOf("会计") != -1) {
//会计审批拒绝：（1）新增一条人员的信息    （2）修改会计待办任务状态
						addMesage("1", "2", "1", bx.getId() + "", bx.getBxlx() + "", "您的报销" + userInfo.getData().getUser().getRealName() + "已拒绝,请修改", user.getUserId() + "", bx.getBxr() + "", "审批拒绝");
						updateBeforeMesage("1", "2", "1", bx.getId() + "", "|6#4|", "已审批");
					}
				} else if (shResult.equals("revoke")) {//撤销报销单
					bx.setShrqm("");
					bx.setShzt(1);
					bxsh.setShzt(3);
//					撤销报销单 删除此单据的所有消息
					updateBeforeMesage("1", "2", "1", bx.getId() + "", "|6#4|", "撤销");
					Message message = new Message();
					message.setXtdm("1");//系统代码（OA、商务等）
					message.setYwmk("2");//业务模块代码（人力资源、报销管理等）
					message.setGlid(bx.getId() + "");//关联id'
					List<Message> messagesList;
					messagesList = messageService.list(Condition.getQueryWrapper(message));
					if (messagesList.size() > 0) {
						for (int q = 0; q < messagesList.size(); q++) {
							messageService.delete(messagesList.get(q).getId());
						}
					}
				}
				bxsh.setBxdid(bxids.get(i));
				bxshService.save(bxsh);
				bxService.updateById(bx);
			}
			return R.status(true);
		} catch (Exception e) {
			e.printStackTrace();
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();// 事务回滚
			return R.status(false);
		}
	}

	/**
	 * 删除报销单
	 */
	@PostMapping("/remove")
	@ApiOperation(value = "删除", notes = "传入报销单ids")
	@Transactional
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		List<Integer> bxids = Func.toIntList(ids);
		R r = new R();
		try {
			for (int i = 0; i < bxids.size(); i++) {
				Bx bx = bxService.getById(bxids.get(i));
				//		查询报销单类型
				Integer bxlx = bx.getBxlx();
				Bxxcmx bxxcmx = new Bxxcmx();
				Bxfymx bxfymx = new Bxfymx();
				Bxzszpmx bxzszpmx = new Bxzszpmx();
				if (bxlx == 1) {//差旅
					bxxcmx.setBxdid(bx.getId());//查询该报销单的所有行程
					List<Bxxcmx> bxxcmxList = bxxcmxService.list(Condition.getQueryWrapper(bxxcmx));
					for (int j = 0; j < bxxcmxList.size(); j++) {
//查询该报销单的所有行程是否关联住宿专票报销 若关联则返回错误信息 退出删除
						bxzszpmx.setClbxdid(bxxcmxList.get(j).getBxdid());//关联报销单id
						bxzszpmx.setBxxcid(bxxcmxList.get(j).getId());//关联的行程id
						List<Bxzszpmx> bxzszpmxList = bxzszpmxService.list(Condition.getQueryWrapper(bxzszpmx));
						if (bxzszpmxList.size() > 0) {
							r.setSuccess(false);
							r.setMsg("该条行程下关联住宿费专用报销" + bxzszpmxList.size() + "条,请先删除");
							return r;
						} else {
//删除报销单下的行程
							bxxcmxService.removeById(bxxcmxList.get(j).getId());
						}
					}
				} else if (bxlx == 2) {//费用
					bxfymx.setBxdid(bx.getId());//查询该报销单的所有行程
					List<Bxfymx> bxfymxList = bxfymxService.list(Condition.getQueryWrapper(bxfymx));
					for (int j = 0; j < bxfymxList.size(); j++) {
//						删除报销单下的费用
						bxfymxService.removeById(bxfymxList.get(j).getId());
					}
				} else if (bxlx == 3) {//住宿费专用
					bxzszpmx.setBxdid(bx.getId());//查询该报销单的所有行程
					List<Bxzszpmx> bxzszpmxList = bxzszpmxService.list(Condition.getQueryWrapper(bxzszpmx));
					for (int j = 0; j < bxzszpmxList.size(); j++) {
//						删除报销单下的行程
						bxzszpmxService.removeById(bxzszpmxList.get(j).getId());
					}
				}
			}
			iInvoiceImageService.remove(new QueryWrapper<InvoiceImage>().in("bx_id",bxids));
			bxshService.remove(new QueryWrapper<Bxsh>().in("bxdid",bxids));
			List<Message> messages = messageService.list(new QueryWrapper<Message>().in("glid", bxids));
			if (messages.size()>0){
				messageService.removeByIds(messages.stream().map(Message::getId).collect(Collectors.toList()));
			}

			return R.status(bxService.deleteLogic(Func.toIntList(ids)));
		} catch (Exception e) {
			e.printStackTrace();
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();// 事务回滚
			return R.status(false);
		}
	}

	/**
	 * 删除报销费用明细
	 */
	@PostMapping("/removeBxfymx")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "删除", notes = "传入报销费用明细ids")
	public R removeBxfymx(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		return R.status(bxfymxService.removeByIds(Func.toIntList(ids)));
	}

	/**
	 * 删除报销行程明细表
	 */
	@PostMapping("/removeBxxcmx")
	@ApiOperation(value = "删除", notes = "传入报销行程明细ids")
	public R removeBxxcmx(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		List<Integer> xcids = Func.toIntList(ids);
		R r = new R();
		for (int i = 0; i < xcids.size(); i++) {
//查询报销单住宿表
			Bxxcmx bxxcmx = bxxcmxService.getById(xcids.get(i));
			Bxzszpmx bxzszpmx = new Bxzszpmx();
			bxzszpmx.setBxxcid(bxxcmx.getId()); //行程的id为住宿专票的关联行程id
			bxzszpmx.setClbxdid(bxxcmx.getBxdid());//行程的报销单id为住宿专票关联的差旅报销单id
			List<Bxzszpmx> bxzszpmxList = bxzszpmxService.list(Condition.getQueryWrapper(bxzszpmx));
//查询该报销单的所有行程是否关联住宿专票报销 若关联则返回错误信息 退出删除
			if (bxzszpmxList.size() > 0) {
				r.setSuccess(false);
				r.setMsg("该条行程下关联住宿费专用报销" + bxzszpmxList.size() + "条,请先删除");
				return r;
			}
		}
		return R.status(bxxcmxService.deleteLogic(Func.toIntList(ids)));
	}

	/**
	 * 删除报销住宿专票明细表
	 */
	@PostMapping("/removeBxzszpmx")
	@ApiOperation(value = "删除", notes = "传入报销住宿专票明细ids")
	public R removeBxzszpmx(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		return R.status(bxzszpmxService.deleteLogic(Func.toIntList(ids)));
	}

	/**
	 * 导出报销单
	 */
	@GetMapping("/export")
	@ApiOperation(value = "导出", notes = "报销单ids")
	public void Export(HttpServletRequest request, HttpServletResponse response, @RequestParam String ids) throws IOException {
		//声明一个工作簿
		List<Map<String, Object>> allBxMapList = new ArrayList<>();
		List<Integer> bxids = Func.toIntList(ids);
		for (int i = 0; i < bxids.size(); i++) {
			List<Bxxcmx> bxxcmxList;
			List<Bxfymx> bxfymxList;
			List<Bxzszpmx> bxzszpmxList;
			List<BxxcmxVO> bxxcmxVOList = null;
			List<BxfymxVO> bxfymxVOList = null;
			List<BxzszpmxVO> bxzszpmxVOList = null;
			BxVo bxVo = null;
			Map<String, Object> map = new HashMap();
			Integer bxdid = bxids.get(i);
			Bx bx = bxService.getById(bxdid);//根据id查询报销单
			Integer bxlx = bx.getBxlx();//报销类型  （差旅费报销单、费用报销单、住宿专票报销单）
			bxVo = BxWrapper.build().entityVO(bx);
			//如果是差旅 则addxcbxd，否则费用报销单和住宿专票addfybxd
			if (bxlx == 1) {//差旅费报销
				Bxxcmx bxxcmx = new Bxxcmx();
				bxxcmx.setBxdid(bxdid);
				bxxcmx.setIsDeleted(0);
				bxxcmxList = bxxcmxService.list(Condition.getQueryWrapper(bxxcmx));
				BigDecimal jtxj = BigDecimal.valueOf(bxxcmxList.stream().mapToDouble(e -> e.getFjje().doubleValue()).reduce(0, Double::sum)).add(BigDecimal.valueOf(bxxcmxList.stream().mapToDouble(e -> e.getHcje().doubleValue()).reduce(0, Double::sum))).add(BigDecimal.valueOf(bxxcmxList.stream().mapToDouble(e -> e.getJcdbje().doubleValue()).reduce(0, Double::sum)));
				bxVo.setJtfjexj(jtxj);
				bxVo.setZsfjexj(BigDecimal.valueOf(bxxcmxList.stream().mapToDouble(e -> e.getZsje().doubleValue()).reduce(0, Double::sum)));
				bxVo.setBtjexj(BigDecimal.valueOf(bxxcmxList.stream().mapToDouble(e -> e.getBtje().doubleValue()).reduce(0, Double::sum)));
				bxVo.setQtjexj(BigDecimal.valueOf(bxxcmxList.stream().mapToDouble(e -> e.getQtje().doubleValue()).reduce(0, Double::sum)));
				bxxcmxVOList = BxxcmxWrapper.build().listVO(bxxcmxList);
			} else if (bxlx == 2) {//费用报销
				Bxfymx bxfymx = new Bxfymx();
				bxfymx.setBxdid(bxdid);
				bxfymxList = bxfymxService.list(Condition.getQueryWrapper(bxfymx));
				bxfymxVOList = BxfymxWrapper.build().listVO(bxfymxList);
			} else if (bxlx == 3) {//专票住宿费报销
				Bxzszpmx bxzszpmx = new Bxzszpmx();
				bxzszpmx.setBxdid(bxdid);
				bxzszpmxList = bxzszpmxService.list(Condition.getQueryWrapper(bxzszpmx));
				bxzszpmxVOList = BxzszpmxWrapper.build().listVO(bxzszpmxList);
			}
			map.put("bx", bxVo);
			map.put("bxlx", bxlx);
			map.put("bxxcmxList", bxxcmxVOList);
			map.put("bxfymxList", bxfymxVOList);
			map.put("bxzszpmxList", bxzszpmxVOList);
			allBxMapList.add(map);
		}
		HSSFWorkbook workbook = bxService.export(allBxMapList, response);
		//准备将Excel的输出
		//流通过response输出到页面下载
		//八进制输出流
		//response.setContentType("application/octet-stream");
		//这后面可以设置导出Excel的名称，此例中名为费用报销单报销.xls
		//response.setHeader("Content-disposition", "attachment;filename=bx.xls");

		String agent = request.getHeader("USER-AGENT").toLowerCase();
		response.setContentType("application/vnd.ms-excel");
		String fileName = "费用报销单";
		String codedFileName = java.net.URLEncoder.encode(fileName, "UTF-8");
		if (agent.contains("firefox")) {
			response.setCharacterEncoding("utf-8");
			response.setHeader("content-disposition", "attachment;filename=" + new String(fileName.getBytes(), "ISO8859-1") + ".xls");
		} else {
			response.setHeader("content-disposition", "attachment;filename=" + codedFileName + ".xls");
		}

		//刷新缓冲
		response.flushBuffer();
		//workbook将Excel写入到response的输出流中，供页面下载
		workbook.write(response.getOutputStream());
	}

	//	//消息表新增数据
	private void addMesage(String xtdm, String ywdm, String xxlx, String glid, String fwlj, String xxnr, String scrid, String jsrfw, String zt) {
		Message message = new Message();
		message.setXtdm(xtdm);//系统代码（OA、商务等）
		message.setYwmk(ywdm);//业务模块代码（人力资源、报销管理等）
		message.setXxlx(xxlx);//消息类型（1.任务 2.消息3.系统通知）
		message.setGlid(glid);//关联id'
		message.setFwlj(fwlj);//访问路径
		message.setXxnr(xxnr);//消息内容
		message.setScrid(scrid);//上传人id
		message.setJsrfw(jsrfw);//角色范围
		message.setSfyd("0");// '是否已读（0：否，1：是）',
		message.setZt(zt);//消息状态（待审批，已审批，驳回等等）',
		messageService.save(message);
		//添加微信公众号推送
		try {
			System.out.println("发送公众号模板消息开始============");
			sendWxMpTemplateMessage(message);
		} catch (Exception e) {
			System.out.println("微信公众号发送模板消息出现异常");
			e.printStackTrace();
		}
	}

	//	//消息表修改数据
	private void updateBeforeMesage(String xtdm, String ywdm, String xxlx, String glid, String jsrfw, String zt) {
		Message message = new Message();
		message.setXtdm(xtdm);//系统代码（OA、商务等）
		message.setYwmk(ywdm);//业务模块代码（人力资源、报销管理等）
		message.setXxlx(xxlx);//消息类型（1.任务 2.消息3.系统通知）
		message.setGlid(glid);//关联id'
		message.setJsrfw(jsrfw);//角色范围
		List<Message> messagesList;
		messagesList = messageService.list(Condition.getQueryWrapper(message));
		if (messagesList.size() > 0) {
			for (int i = 0; i < messagesList.size(); i++) {
				Message me = messagesList.get(i);
				Message msge = messageService.getMsgById(me.getId());
				msge.setZt(zt);
				msge.setId(me.getId());
				messageService.update(msge);
			}
		}
	}

	/**
	 * 获取用户未提交报销单信息
	 *
	 * @return
	 */
	@GetMapping("/getClbxd")
	@ApiOperation(value = "获取报销单信息", notes = "获取报销单信息")
	public R<List<Bx>> getClbxd(BladeUser user) {
		Integer shzt = 6;//去掉审批终结状态
		Integer bxlx = 1;//仅要差旅费报销
		List<Bx> tree = bxService.getList(user.getUserId(), bxlx, shzt);
		return R.data(tree);
	}

	/**
	 * 获取行程已报销天数
	 *
	 * @return
	 */
	@GetMapping("/getBxDays")
	@ApiOperation(value = "获取报销单信息", notes = "获取报销单信息")
	public R getBxDays(String startTime, String endTime, String id, BladeUser user) {
		SimpleDateFormat yymmdd = new SimpleDateFormat("yyyy-MM-dd");
		Integer userId;
		if ("0".equals(id)) {
			userId = user.getUserId();
		} else {
			userId = bxService.getById(id).getCreateUser();
		}
		List<Map<String, Object>> dayList = bxxcmxService.getBxDays(startTime, endTime, Integer.valueOf(id), userId);
		int n = 0;
		if (dayList.size() > 0) {
			String tj = dayList.get(0).get("kssj").toString();
			String tj1 = dayList.get(0).get("jssj").toString();

			try {
				Date kssj = yymmdd.parse(dayList.get(0).get("kssj").toString());
				Date jssj = yymmdd.parse(dayList.get(dayList.size() - 1).get("jssj").toString());
				if (tj.equals(startTime) || tj1.equals(startTime)) {
					n = 1;
				} else {
					Calendar cal = Calendar.getInstance();
					cal.setTime(kssj);
					long time1 = cal.getTimeInMillis();
					cal.setTime(jssj);
					long time2 = cal.getTimeInMillis();
					long between_days = (time2 - time1) / (1000 * 3600 * 24) + 1;
					n = Integer.parseInt(String.valueOf(between_days));
				}
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		return R.data(n);
	}

	/**
	 * 发送微信公众号模板消息
	 *
	 * @param message
	 */
//	@GetMapping(value = "/send")
	public void sendWxMpTemplateMessage(Message message) {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		List<String> openIdList = getUserOpenID(message);
		String xxlx;
		String scrName = "";
		String dateTime = "";
		String xxnr = "";
		String zt = "";
		for (String openId : openIdList) {
			List<MyWxMpTemplateMessage> myWxMpTemplateMessageList = new ArrayList<>();
			MyWxMpTemplateMessage myWxMpTemplateMessage = new MyWxMpTemplateMessage();
			myWxMpTemplateMessage.setToUser(openId);
			myWxMpTemplateMessage.setUrl("http://118.190.141.98:8199/#/login");
			List<MyWxMpTemplateData> myWxMpTemplateDataList = new ArrayList<>();
			//消息类型
			xxlx = message.getXxlx();
			//上传人id
			String scrid = message.getScrid();
			R<UserInfo> userInfo = userClient.userInfo(Long.valueOf(scrid));
			if (userInfo.isSuccess()) {
				scrName = userInfo.getData().getUser().getRealName();
			}
			dateTime = simpleDateFormat.format(message.getCreateTime());
			xxnr = message.getXxnr();
			zt = message.getZt();
			System.out.println("消息类型为：" + xxlx);
			if ("1".equals(xxlx)) {
				//待办任务
				myWxMpTemplateDataList.add(new MyWxMpTemplateData("first", "您有一个待审批事项", "#75C348"));
				myWxMpTemplateDataList.add(new MyWxMpTemplateData("keyword1", "报销申请", "#75C348"));
				myWxMpTemplateDataList.add(new MyWxMpTemplateData("keyword2", scrName, "#75C348"));
				myWxMpTemplateDataList.add(new MyWxMpTemplateData("keyword3", dateTime, "#75C348"));
				myWxMpTemplateDataList.add(new MyWxMpTemplateData("keyword4", xxnr, "#75C348"));
				myWxMpTemplateDataList.add(new MyWxMpTemplateData("remark", zt, "#75C348"));
			} else if ("2".equals(xxlx)) {
				//消息提醒
				myWxMpTemplateDataList.add(new MyWxMpTemplateData("first", "您的申请已被审批", "#75C348"));
				myWxMpTemplateDataList.add(new MyWxMpTemplateData("keyword1", zt, "#75C348"));
				myWxMpTemplateDataList.add(new MyWxMpTemplateData("keyword2", scrName, "#75C348"));
				myWxMpTemplateDataList.add(new MyWxMpTemplateData("keyword3", dateTime, "#75C348"));
				myWxMpTemplateDataList.add(new MyWxMpTemplateData("remark", xxnr, "#75C348"));
			} else {
				//系统通知
				System.out.println("方法直接返回了！");
				return;
			}
			myWxMpTemplateMessage.setData(myWxMpTemplateDataList);
			myWxMpTemplateMessageList.add(myWxMpTemplateMessage);
			String myWxMpTemplateMessageListStr = JSON.toJSONString(myWxMpTemplateMessageList);
			System.out.println("下一句为发送模板消息");
			R<HashMap<String, Object>> result = mpClient.sendWxMpTemplateMessage(myWxMpTemplateMessageListStr, xxlx);
			System.out.println("微信模板消息服务响应状态码：" + result.getCode());
			if (result.getCode() == 200) {
				System.out.println("微信公众服务状态码：" + result.getData().get("Status"));
				System.out.println("微信公众服务信息：" + result.getData().get("msg"));
			}
		}
	}

	/**
	 * 获取用户openID
	 *
	 * @param message
	 * @return
	 */
	public List<String> getUserOpenID(Message message) {
		System.out.println("获取用户openid=======message：" + message.toString());
		List<String> openIdList = new ArrayList<>();
		String openId = "";
		//公众号唯一标识
		Integer mpId = 1;
		//获取消息类型
		String xxlx = message.getXxlx();
		//获取接收人范围
		String jsrfw = message.getJsrfw();
		Integer userId;
		if ("1".equals(xxlx)) {
			//消息(待办任务：所属部门+角色（部门审批负责人）)
			String[] deptAndRole = jsrfw.substring(1, jsrfw.length() - 1).split("#");
			R<List<UserInfo>> userInfoList;
			if("4".equals(deptAndRole[1]) || "5".equals(deptAndRole[1])){
				userInfoList = userClient.userInfo(null,deptAndRole[1]);
			} else {
				userInfoList = userClient.userInfo(deptAndRole[0], deptAndRole[1]);
			}

			if (userInfoList.isSuccess()) {
				for (UserInfo datum : userInfoList.getData()) {
					userId = datum.getUser().getId();
					//获取openID
//					userId = 57;
					System.out.println("在这里调用微信服务");
					R<String> openIdR = mpClient.getOpenIdByMpIdAndUserId(mpId.toString(), userId.toString());
					if (openIdR.isSuccess()) {
						openId = openIdR.getData();
						openIdList.add(openId);
					}
				}
			}
		} else if ("2".equals(xxlx)) {
			//消息
			userId = Integer.parseInt(jsrfw);
			R<UserInfo> userInfo = userClient.userInfo(Long.valueOf(userId));
			if (userInfo.isSuccess()) {
				userId = userInfo.getData().getUser().getId();
				//获取openID
				R<String> openIdR = mpClient.getOpenIdByMpIdAndUserId(mpId.toString(), userId.toString());
				if (openIdR.isSuccess()) {
					openId = openIdR.getData();
					openIdList.add(openId);
				}
			}
			//查询用户openID
		} else if ("3".equals(xxlx)) {
			//系统通知
		}
		System.out.println("用户openIdList为：" + openIdList);
		return openIdList;
	}

	@GetMapping("/exportBx")
	public void exportBx(HttpServletResponse response,HttpServletRequest request,ExpenseAccount expenseAccount) throws IOException {
		Workbook workbook = bxService.exportBx(expenseAccount);
		String agent = request.getHeader("USER-AGENT").toLowerCase();
//		response.setContentType("application/vnd.ms-excel");
		response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
		String fileName = "费用报销单";
		String codedFileName = java.net.URLEncoder.encode(fileName, "UTF-8");
		if (agent.contains("firefox")) {
			response.setCharacterEncoding("utf-8");
			response.setHeader("content-disposition", "attachment;filename=" + new String(fileName.getBytes(), "ISO8859-1") + ".xls");
		} else {
			response.setHeader("content-disposition", "attachment;filename=" + codedFileName + ".xlsx");
		}
		//刷新缓冲
		response.flushBuffer();
		//workbook将Excel写入到response的输出流中，供页面下载
		workbook.write(response.getOutputStream());
	}
}
